package com.agile.leetcode.rpc.client;

import cn.hutool.json.JSONUtil;
import com.agile.leetcode.rpc.pojo.CalculatorRpcRequest;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

/**
 * @Author KD
 * @Date 2021/1/20 14:35
 */
public class NioClient {
    /**
     * 主机
     */
    private static final String HOST = "127.0.0.1";
    /**
     * 端口
     */
    private static final int PORT = 7001;
    /**
     * channel
     */
    private SocketChannel socketChannel;
    /**
     * 选择器
     */
    private Selector selector;

    public NioClient() {
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress(HOST, PORT));
            // 注册
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
            // 连接
            System.out.println(socketChannel.getRemoteAddress() + "准备好了");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 发送数据
     *
     * @param calculatorRpcRequest
     * @throws IOException
     */
    public void sendMessage(CalculatorRpcRequest calculatorRpcRequest) throws IOException {
        // 转为json
        String jsonStr = JSONUtil.toJsonStr(calculatorRpcRequest);
        // 发送
        socketChannel.write(ByteBuffer.wrap(jsonStr.getBytes()));
    }

    /**
     * 读取消息
     *
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public void readMessage() {
        try {
            // 拿到连接的
            int i = selector.select();
            if (i > 0) {
                // 拿到通道
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    // 拿到
                    SelectionKey key = iterator.next();
                    // 判断状态
                    if (key.isReadable()) {
                        // 拿到通道
                        SocketChannel channel = (SocketChannel) key.channel();
                        // 配置非阻塞
                        channel.configureBlocking(false);
                        // 拿到数据
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int read = channel.read(buffer);
                        if (read != -1) {
                            System.out.println(new String(buffer.array()));
                        }
                    }
                    iterator.remove();
                }
            }
        } catch (Exception ex) {

        }
    }

    public static void main(String[] args) throws IOException {
        NioClient client = new NioClient();
        new Thread(() -> {

            while (true) {
                try {
                    client.readMessage();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }).start();
        client.sendMessage(new CalculatorRpcRequest(1, 2, "add"));

    }
}
